package gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import parsers.HtmlParser;
import rsshunter.RSSChannel;
import rsshunter.RSSKeyword;

/**
 * Frame representing html base properties.
 */
public class HtmlBaseFrame extends RssBaseFrame {

    private Set<String> newUris;

    public HtmlBaseFrame(MainFrame parent) {
        super(parent);
        this.newUris = new HashSet<String>();
        setLabels();
        changeListeners();
    }

    @Override
    protected void updateBaseData() {
        super.updateBaseData();
        if (!newUris.isEmpty()) {
            createNewContentFiles();
        }
        newUris.clear();
    }

    /**
     * Set specific labels for html base frame.
     */
    private void setLabels() {
        jTabbedPane1.setTitleAt(0, "Html addresses");
        jTabbedPane1.setTitleAt(1, "Tags");
        jButton1.setText("New uri");
        jButton2.setText("Edit uri");
        jButton3.setText("Delete uri");
        jButton4.setText("New keytag");
        jButton5.setText("Edit keytag");
        jButton6.setText("Delete keytag");
    }

    /**
     * Change superclass listeners for htmlBaseFrame specific.
     */
    private void changeListeners() {
        jButton1.removeActionListener(jButton1.getActionListeners()[0]);
        jButton1.addActionListener(new addNewUriListener());

        jButton2.removeActionListener(jButton2.getActionListeners()[0]);
        jButton2.addActionListener(new editUriListener());

        jButton3.removeActionListener(jButton3.getActionListeners()[0]);
        jButton3.addActionListener(new removeUriListener());

        jButton4.removeActionListener(jButton4.getActionListeners()[0]);
        jButton4.addActionListener(new addTagListener());

        jButton5.removeActionListener(jButton5.getActionListeners()[0]);
        jButton5.addActionListener(new editTagListener());
    }

    /**
     * Create content files for new uris.
     */
    private void createNewContentFiles() {
        List<RSSChannel> channels = db.getChannels(newUris.toArray(new String[0]), actualBase);
        try {
            HtmlParser.initChannels(channels, getTags());
            newUris.clear();
        } catch (MalformedURLException e) {
            String uri = e.getMessage();
            deleteUri(uri);
            parent.setStatus("Broken uri " + uri + " was deleted.");
            if (!newUris.isEmpty()) {
                createNewContentFiles();
            }
        }
    }

    /**
     * Get actual base tags.
     *
     * @return List of RSSKeywords containing tags.
     */
    private List<RSSKeyword> getTags() {
        List<RSSKeyword> result = new LinkedList<RSSKeyword>();
        DefaultListModel model = (DefaultListModel) jList2.getModel();
        Object[] tags = model.toArray();
        for (Object o : tags) {
            String keyTag = (String) o;
            result.add(new RSSKeyword(keyTag, actualBase));
        }
        return result;
    }

    /**
     * Delete uri from database, model, and newUris list.
     */
    private void deleteUri(String uri) {
        RSSChannel toDelete = new RSSChannel(null, uri, null, null, actualBase);
        newUris.remove(uri);
        db.deleteChannel(toDelete);
        channelsModel.removeElement(uri);
    }

    /*
     * ============== Button listners ==============
     */
    private class addNewUriListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (actualBase == null) {
                return;
            }
            String uri = JOptionPane.showInputDialog(rootPane,
                    "Type new uri address:",
                    "Add uri",
                    JOptionPane.PLAIN_MESSAGE);
            if (uri == null || uri.equals("")) {
                return;
            }
            uri = checkUri(uri);

            newUris.add(uri);
            db.addChannel(new RSSChannel(null, uri, null, null, actualBase));
            channelsModel.addElement(uri);
        }
    }

    private class editUriListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String uri = (String) jList1.getSelectedValue();
            int index = jList1.getSelectedIndex();
            if (uri == null || actualBase == null) {
                return;
            }

            String newUri = JOptionPane.showInputDialog(rootPane,
                    "Edit uri:",
                    uri);
            if (newUri == null || newUri.equals("")) {
                return;
            }
            uri = checkUri(uri);

            newUris.add(uri);
            db.updateChannel(new RSSChannel(null, uri, null, null, actualBase), newUri);
            channelsModel.setElementAt(newUri, index);
        }
    }

    private class removeUriListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String uri = (String) jList1.getSelectedValue();
            if (uri == null || actualBase == null) {
                return;
            }

            if (!newUris.contains(uri)) {
                RSSChannel toDelete = db.getChannel(uri, actualBase);
                HtmlParser.deletePageContentFile(toDelete);
            }
            deleteUri(uri);
        }
    }

    private class addTagListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (actualBase == null) {
                return;
            }
            String newTag = JOptionPane.showInputDialog(rootPane,
                    "Type new Tag:",
                    "Add tag",
                    JOptionPane.PLAIN_MESSAGE);
            if (newTag == null || newTag.equals("")) {
                return;
            }
            newTag = newTag.replace("<", "");
            newTag = newTag.replace(">", "");

            db.addKeyword(new RSSKeyword(newTag, actualBase));
            keywordsModel.addElement("<" + newTag + ">");
        }
    }

    private class editTagListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String tag = (String) jList2.getSelectedValue();
            int index = jList2.getSelectedIndex();
            if (tag == null || actualBase == null) {
                return;
            }
            tag = tag.replace("<", "");
            tag = tag.replace(">", "");

            String newKeyword = JOptionPane.showInputDialog(rootPane,
                    "Edit Tag:",
                    tag);
            if (newKeyword == null || newKeyword.equals("")) {
                return;
            }

            db.updateKeyword(new RSSKeyword(tag, actualBase), newKeyword);
            keywordsModel.setElementAt("<" + newKeyword + ">", index);
        }
    }
}